import traceback
from dataclasses import dataclass
from datetime import datetime
from enum import Enum, auto
from typing import Dict, Type, Callable, Optional

from PySide6.QtWidgets import QMessageBox

from ..事件系统.事件管理器 import 事件管理器实例, 事件类型, 异常事件数据
from ..日志系统.日志管理器 import 日志管理器实例


class 异常级别(Enum):
    """异常的严重程度"""
    信息 = auto()
    警告 = auto()
    错误 = auto()
    严重 = auto()
    致命 = auto()

@dataclass
class 异常信息:
    """异常的详细信息"""
    异常类型: str
    异常消息: str
    堆栈信息: str
    发生时间: datetime
    级别: 异常级别
    源对象: Optional[object] = None
    额外信息: Dict = None

class 自定义异常(Exception):
    """自定义异常基类"""
    def __init__(self, 消息: str, 级别: 异常级别 = 异常级别.错误):
        super().__init__(消息)
        self.级别 = 级别
        self.发生时间 = datetime.now()

class 节点异常(自定义异常):
    """节点相关的异常"""
    pass

class 连接异常(自定义异常):
    """连接相关的异常"""
    pass

class 文件操作异常(自定义异常):
    """文件操作相关的异常"""
    pass

class 异常管理器:
    """统一的异常管理器"""
    
    def __init__(self):
        self.日志器 = 日志管理器实例.获取日志器("异常管理器")
        self._异常处理器: Dict[Type[Exception], Callable] = {}
        self._异常历史: List[异常信息] = []
        self._初始化默认处理器()
        
    def _初始化默认处理器(self):
        """初始化默认的异常处理器"""
        self.注册处理器(节点异常, self._处理节点异常)
        self.注册处理器(连接异常, self._处理连接异常)
        self.注册处理器(文件操作异常, self._处理文件异常)
        self.注册处理器(Exception, self._处理通用异常)
        
    def 注册处理器(self, 异常类型: Type[Exception], 处理函数: Callable):
        """注册异常处理器
        
        Args:
            异常类型: 要处理的异常类型
            处理函数: 处理异常的函数
        """
        self._异常处理器[异常类型] = 处理函数
        self.日志器.debug(f"注册异常处理器: {异常类型.__name__} -> {处理���数.__name__}")
        
    def 处理异常(self, 异常: Exception, 源对象: Optional[object] = None):
        """处理异常
        
        Args:
            异常: 异常对象
            源对象: 产生异常的对象
        """
        try:
            # 获取异常信息
            异常类型 = type(异常)
            异常消息 = str(异常)
            堆栈信息 = traceback.format_exc()
            级别 = 异常级别.错误
            
            if isinstance(异常, 自定义异常):
                级别 = 异常.级别
                
            # 创建异常信息对象
            信息 = 异常信息(
                异常类型=异常类型.__name__,
                异常消息=异常消息,
                堆栈信息=堆栈信息,
                发生时间=datetime.now(),
                级别=级别,
                源对象=源对象
            )
            
            # 记录异常历史
            self._异常历史.append(信息)
            
            # 记录日志
            self._记录异常日志(信息)
            
            # 触发异常事件
            self._触发异常事件(信息)
            
            # 调用对应的处理器
            for 异常类, 处理器 in self._异常处理器.items():
                if isinstance(异常, 异常类):
                    处理器(信息)
                    break
                    
        except Exception as e:
            self.日志器.error(f"处理异常时发生错误: {str(e)}")
            
    def _记录异常日志(self, 信息: 异常信息):
        """记录异常日志"""
        日志消息 = (
            f"异常发生:\n"
            f"类型: {信息.异常类型}\n"
            f"消息: {信息.异常消息}\n"
            f"级别: {信息.级别.name}\n"
            f"时间: {信息.发生时间}\n"
            f"堆栈信息:\n{信息.堆栈信息}"
        )
        
        if 信息.级别 in [异常级别.错误, 异常级别.严重, 异常级别.致命]:
            self.日志器.error(日志消息)
        else:
            self.日志器.warning(日志消息)
            
    def _触发异常事件(self, 信息: 异常信息):
        """触发异常事件"""
        事件数据 = 异常事件数据(
            类型=事件类型.异常发生,
            源对象=信息.源对象,
            异常类型=信息.异常类型,
            异常信息=信息.异常消息,
            堆栈信息=信息.堆栈信息
        )
        事件管理器实例.触发事件(事件数据)
        
    def _处理节点异常(self, 信息: 异常信息):
        """处理节点相关的异常"""
        QMessageBox.warning(
            None,
            "节点错误",
            f"节点操作出错: {信息.异常消息}"
        )
        
    def _处理连接异常(self, 信息: 异常信息):
        """处理连接相关的异常"""
        QMessageBox.warning(
            None,
            "连接错误",
            f"节点连接出错: {信息.异常消息}"
        )
        
    def _处理文件异常(self, 信息: 异常信息):
        """处理文件操作相关的异常"""
        QMessageBox.critical(
            None,
            "文件错误",
            f"文件操作失败: {信息.异常消息}"
        )
        
    def _处理通用异常(self, 信息: 异常信息):
        """处理通用异常"""
        QMessageBox.critical(
            None,
            "错误",
            f"发生错误: {信息.异常消息}\n\n详细信息已记录到日志"
        )
        
    def 获取异常历史(self, 开始时间: Optional[datetime] = None,
                 结束时间: Optional[datetime] = None,
                 级别: Optional[异常级别] = None) -> List[异常信息]:
        """获取异常历史记录
        
        Args:
            开始时间: 开始时间
            结束时间: 结束时间
            级别: 异常级别
            
        Returns:
            List[异常信息]: 符合条件的异常记录
        """
        结果 = self._异常历史
        
        if 开始时间:
            结果 = [x for x in 结果 if x.发生时间 >= 开始时间]
        if 结束时间:
            结果 = [x for x in 结果 if x.发生时间 <= 结束时间]
        if 级别:
            结果 = [x for x in 结果 if x.级别 == 级别]
            
        return 结果
        
    def 清除异常历史(self):
        """清除异常历史记录"""
        self._异常历史.clear()
        self.日志器.info("异常历史记录已清除")
        
# 创建全局异常管理器实例
异常管理器实例 = 异常管理器()

# 异常处理装饰器
def 异常处理(异常类型: Type[Exception] = Exception):
    """异常处理装饰器
    
    Args:
        异常类型: 要捕获的异常类型
    """
    def 装饰器(func):
        def 包装(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except 异常类型 as e:
                异常管理器实例.处理异常(e, args[0] if args else None)
                raise
        return ���装
    return 装饰器 